﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Windows.Forms;
using DevExpress.XtraEditors;
using Fcdbas.Platform.Properties;
using Fcdbas.WinUI.Forms;

namespace Fcdbas.WinUI.Controls
{
    [Description("表示 Fcdbase 可编辑按钮。")]
    [ToolboxBitmap(typeof(ButtonEdit))]
    [ToolboxItemFilter("System.Windows.Forms")]
    public class cButtonEdit : ButtonEdit, IReference, IOwningDataSourceBinding, IReadOnly, IValidate, IControl
    {
        private DataItem dataItem;
        /// <summary>
        /// 绑定的字段信息
        /// </summary>
        [Browsable(true)]
       // [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Content)]
        public DataItem DataColumn
        {
            get { return dataItem; }
            set
            {
                if (value == null)
                    return;
                dataItem = value;
                if (OwningDataSourceBinding != null && OwningDataSourceBinding.Updates == Platform.Enums.UpdatesSql.ReadOnly)
                    this.ReadOnly = true;
                this.Properties.MaxLength = dataItem.Length;
                if (dataItem.DataType == typeof(int) )
                    IsNumber = true;
                if (dataItem.DataType == typeof(decimal) ||
                   dataItem.DataType == typeof(double) ||
                   dataItem.DataType == typeof(Int16) ||
                   dataItem.DataType == typeof(int) ||
                   dataItem.DataType == typeof(Int64) ||
                   dataItem.DataType == typeof(Single) ||
                   dataItem.DataType == typeof(UInt16) ||
                   dataItem.DataType == typeof(uint) ||
                   dataItem.DataType == typeof(UInt64))
                {
                    if (string.IsNullOrEmpty(WinUI.Common.WinUtil.GetFormatMask(dataItem.FormatOption)))
                    {
                        this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.None;
                        this.Properties.Mask.EditMask = "";
                        this.Properties.Mask.UseMaskAsDisplayFormat = true;
                    }
                    else 
                    {
                         this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
                        this.Properties.Mask.EditMask = string.IsNullOrEmpty(dataItem.CustomerFormat) ? WinUI.Common.WinUtil.GetFormatMask(dataItem.FormatOption) : dataItem.CustomerFormat;
                        this.Properties.Mask.UseMaskAsDisplayFormat = true;
                    }
                    

                }
                if (dataItem.DataType == typeof(string))
                {
                    if (dataItem.FormatOption.ToUpper() == "UPPERCASE")
                        this.Properties.CharacterCasing = CharacterCasing.Upper;
                    else if (dataItem.FormatOption.ToUpper() == "LOWERCASE")
                        this.Properties.CharacterCasing = CharacterCasing.Lower;
                }
                IsNeedValid = dataItem.Required;
                if (!IsNeedValid)
                    this.Properties.AllowNullInput = DevExpress.Utils.DefaultBoolean.True;
                if (dataItem.Alignment != (int)DevExpress.Utils.HorzAlignment.Default)
                    this.Properties.Appearance.TextOptions.HAlignment = (DevExpress.Utils.HorzAlignment)dataItem.Alignment;
            }
        }
        public bool IsDelete
        {
            set
            {
                if (value)
                {
                    Font font = new Font(this.Font, FontStyle.Strikeout);
                    this.Font = font;
                    oldForeColor = this.ForeColor;
                    this.ForeColor = Fcdbas.WinUI.Common.AppEnvironment.AppOption.DeleteColor;
                }
                else
                {
                    Font font = new Font(this.Font, FontStyle.Regular);
                    this.Font = font;
                    this.ForeColor = oldForeColor;
                }
            }
        }
       

        #region IReference 成员
        private bool _isEditing;
        public bool IsEditing
        {
            get
            {
                return _isEditing;
            }
            set
            {
                _isEditing = value;
                //if (value)
                //{
                //    this.oldForeColor = this.ForeColor;
                //    this.ForeColor = Fcdbas.WinUI.Common.AppEnvironment.AppOption.EditColor;
                //}
                //else
                //{
                //    this.ForeColor = oldForeColor;
                //}
            }
        }
        public bool IsReference
        {
            get
            {
                return !string.IsNullOrEmpty(Reference);
            }
        }

        public string Reference
        {
            get
            {
                DataItem bindingItem = GetBindingItem();
                if (bindingItem != null)
                    return bindingItem.Reference;

                return null;
            }
        }
        public string Value
        {
            get
            {
                return this.Text;
            }
            set
            {
                this.Text = value;
            }
        }
        private string columnName;
        public string Column
        {
            get
            {
                DataItem bindingItem = GetBindingItem();
                if (bindingItem != null)
                    return bindingItem.ColumnName;
                else
                    return columnName;
            }
            set
            {
                DataItem bindingItem = GetBindingItem();
                if (bindingItem != null)
                    bindingItem.ColumnName = value;
                columnName = value;
            }
        }

        public Type DataType
        {
            get
            {
                DataItem bindingItem = GetBindingItem();
                if (bindingItem != null)
                    return bindingItem.DataType;

                return null;
            }
        }

        public object ReferenceValue
        {
            get
            {
                if (DataColumn != null)
                    return DataColumn.LogicalParent;
                else
                    return null;
                //return this.Text;
            }
        }

        public void SetValue(object value)
        {
            if (value == null ||
                value is DBNull)
                return;

            this.Text = value.ToString();
        }

        #endregion

        private DataItem GetBindingItem()
        {
            return DataColumn;
           
        }

        private DataSourceBinding GetOwningDataSourceBinding()
        {
            if (this.DataBindings["Text"] == null)
            {
                if (OldBinding != null)
                    return OldBinding.DataSource as DataSourceBinding;
                else
                    return null;
            }
            return this.DataBindings["Text"].DataSource as DataSourceBinding;
        }
        #region IOwningDataSourceBinding 成员
        private Binding _oldBinding;
        public Binding OldBinding
        {
            get
            {
                return _oldBinding;
            }
            set
            {
                _oldBinding = value;
            }
        }
        [Browsable(false)]
        public DataSourceBinding OwningDataSourceBinding
        {
            get { return GetOwningDataSourceBinding(); }
        }

        [Browsable(false)]
        DataSourceBinding IOwningDataSourceBinding.OwningDataSourceBinding
        {
            get { return OwningDataSourceBinding; }
        }

        [Browsable(false)]
        public DataItem BindingItem
        {
            get
            {
                return GetBindingItem();
            }
        }

        #endregion

        #region IReadOnly 成员
        private Color oldForeColor = Color.Black ;
        public virtual bool ReadOnly
        {
            get
            {
                return this.Properties.ReadOnly;
            }
            set
            {
                this.Properties.ReadOnly = value;
                if (value)
                {
                    oldForeColor = this.ForeColor;
                    this.ForeColor = Fcdbas.WinUI.Common.AppEnvironment.AppOption.ReadOnlyColor;
                }
                else
                {
                    this.ForeColor = oldForeColor;
                }

            }
        }

        #endregion

        protected override void OnTextChanged(EventArgs e)
        {
            if (OwningDataSourceBinding != null)
            {
                if (OwningDataSourceBinding.Updates == Platform.Enums.UpdatesSql.ReadOnly)
                    return;
                //if (!OwningDataSourceBinding.AllowEdit)
                //    return;
                if (this.DataColumn != null && this.DataColumn.IsAssist)
                    return;
                if (!OwningDataSourceBinding.Session.IsNew && !OwningDataSourceBinding.Session.IsEdit && !OwningDataSourceBinding.Binding && !OwningDataSourceBinding.Session.RecordRefresh)
                {
                    Form frm = WinUI.Common.WinUtil.GetParentForm(this);
                    if (frm != null)
                        Fcdbas.Core.Windows.SalWindow.FireWindowActions(frm, Fcdbas.Platform.Const.AM_DataSourceFieldModified, 1, OwningDataSourceBinding.Identify);
                    IsEditing = true;
                }
            }
            FireRef = true;
            base.OnTextChanged(e);
        }
       
        protected override void OnEnter(EventArgs e)
        {
            BaseForm parentForm = this.FindForm() as BaseForm;
            if (parentForm != null)
                parentForm.FireOnEnterEvent(this);

            base.OnEnter(e);
        }
        private Color oldBackColor;
        protected override void OnGotFocus(EventArgs e)
        {
            oldBackColor = this.BackColor;
            this.BackColor = Fcdbas.WinUI.Common.AppEnvironment.AppOption.FocusColor;
            base.OnGotFocus(e);
        }
        /// <summary>
        /// 触发获取引用字段
        /// </summary>
        private bool FireRef = false;
        protected override void OnLostFocus(EventArgs e)
        {
            this.BackColor = oldBackColor;
            if (FireRef)
            {
                BaseForm parentForm = this.FindForm() as BaseForm;
                if (parentForm != null)
                    parentForm.FireOnTextChangedEvent(this);
                FireRef = false;
            }
            base.OnLostFocus(e);
        }
        private bool IsStandardCH(string str)
        {
            System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex(@"^[A-Z0-9]+$");
            return reg.IsMatch(str);
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0302)
            {
                IDataObject iData = Clipboard.GetDataObject();//取剪贴板对象 
                if (!canPaste)
                {
                    if (iData.GetDataPresent(DataFormats.Text))   //判断是否是Text 
                    {
                        string str = (string)iData.GetData(DataFormats.Text);//取数据 
                        if (IsStandardCH(str))
                        {
                            base.WndProc(ref   m);

                        }
                        else
                            m.Result = (IntPtr)0;
                    }
                    else
                        m.Result = (IntPtr)0;//不可以粘贴 
                }
                else
                    base.WndProc(ref m);
                return;
            }
            if (m.Msg.ToString() == "13")
            {
                base.WndProc(ref m);
            }
            else
            {
                if (m.WParam.ToString() == "2")
                {
                    //d.AddLog(m.Msg.ToString() + ":" + m.ToString());
                    //base.WndProc (ref m);

                    //modify by HY 20080731 原来屏蔽右键消息
                    base.WndProc(ref m);//显示右键菜单
                    //*
                }
                else
                {
                    base.WndProc(ref m);
                }
            }
        }
		
        private bool canPaste = true;
        /// <summary>
        /// 是否允许粘贴非标准字符
        /// </summary>
        [Description("是否允许粘贴非标准字符")]
        [Category("Appearance")]
        [DefaultValue(true)]
        public bool CanPaste
        {
            get
            {
                return canPaste;
            }
            set
            {
                canPaste = value;
            }
        }
        private bool isNumber;
        /// <summary>
        /// 是否是数值类型
        /// </summary>
        [Description("是否是整型数值类型")]
        [Category("Appearance")]
        [DefaultValue(false)]
        public bool IsNumber
        {
            get
            {
                return isNumber;
            }
            set
            {
                isNumber = value;
                if (isNumber)
                {
                    this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
                    this.Properties.Mask.EditMask = "d";
                    this.Properties.Mask.UseMaskAsDisplayFormat = true;
                }
                else
                {
                    this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.None;
                    this.Properties.Mask.EditMask = "";
                }
                if (isNumber)
                {
                    isNumChar = false;
                    isNegative = false;
                }
            }
        }
        private bool isNegative;
        /// <summary>
        /// 能否是负数
        /// </summary>
        [Description("能否是负数")]
        [Category("Appearance")]
        [DefaultValue(false)]
        public bool IsNegative
        {
            get
            {
                return isNegative;
            }
            set
            {
                isNegative = value;
                if (isNegative)
                {
                    this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.Numeric;
                    this.Properties.Mask.EditMask = "f";
                    this.Properties.Mask.UseMaskAsDisplayFormat = true;
                    isNumber = false;
                    isNumChar = false;
                }
                else
                {
                    this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.None;
                    this.Properties.Mask.EditMask = "";
                }
            }
        }
        private float numMaxvalue;
        /// <summary>
        /// 最大值
        /// </summary>
        [Description("最大值")]
        [Category("Appearance")]
        [DefaultValue(1000.00)]
        public float NumMaxValue
        {
            get
            {
                return numMaxvalue;
            }
            set
            {
                numMaxvalue = value;
            }
        }
        private bool isNumChar;
        /// <summary>
        /// 只能是数字和大写字母
        /// </summary>
        [Description("只能是数字和大写字母")]
        [Category("Appearance")]
        [DefaultValue(false)]
        public bool IsNumChar
        {
            get
            {
                return isNumChar;
            }
            set
            {
                isNumChar = value;
                if (isNumChar)
                {
                    this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.RegEx;
                    this.Properties.Mask.EditMask = "[A-Z0-9]{1,200}";
                    isNumber = false;
                    isNegative = false;
                }
                else
                {
                    this.Properties.Mask.MaskType = DevExpress.XtraEditors.Mask.MaskType.None;
                    this.Properties.Mask.EditMask = "";
                }
            }
        }
        private cLabel bindLabel;
        public cLabel BindLabel
        {
            get
            {
                return this.bindLabel;
            }
            set
            {
                this.bindLabel = value;
            }
        }

        public string Label
        {
            get
            {
                if (bindLabel != null)
                    return bindLabel.Text;
                else
                    return "";
            }
                
        }
        /// <summary>
        /// 是否需要进行数据校验
        /// </summary>
        [Description("是否需要进行数据校验")]
        [Category("Appearance")]
        [DefaultValue(false)]
        public bool IsNeedValid
        {
            get;
            set;
        }
      //  protected override bool onvalue
        protected override bool OnInvalidValue(Exception sourceException)
        {
            if (IsNeedValid)
                return base.OnInvalidValue(sourceException);
            else
            {
                if (this.EditValue == null || string.IsNullOrEmpty(Text) || Text == "." || this.EditValue.ToString () != Text )
                {
                    DataSourceBinding ownerDataSourceBinding = GetOwningDataSourceBinding();
                    Fcdbas.Core.IEntity en = ownerDataSourceBinding.Current as Fcdbas.Core.IEntity;
                    if (en != null && this.DataColumn != null)
                        en[this.DataColumn.ColumnName] = null;
                }
                return true;
            }
        }
        public bool Validate()
        {
            DataSourceBinding ownerDataSourceBinding = GetOwningDataSourceBinding();
            if (dataItem != null &&
                   dataItem.Required &&
                   string.IsNullOrEmpty(this.Text))
            {

                WinUI.Forms.BaseForm form = this.FindForm() as WinUI.Forms.BaseForm;
                if (form != null)
                    form.ShowMessage("字段[%%1]不能为空！", dataItem.Caption, MessageBoxButtons.OK, MessageBoxIcon.Warning);
                return false;
            }

            return ownerDataSourceBinding.Validate(this.DataColumn.ColumnName, this.Text);
        }
    }
}
